#ifndef SOCKET_STREAM_H 
#define SOCKET_STREAM_H 

#include "../stream.h"
#include "../socket.h"
#include "../io_manager.h"

#include <shared_mutex>

//封装socket的接收和发送接口
class SocketStream : public Stream 
{
public:
    /**
     * @brief 构造函数
     * @param[in] sock Socket类
     * @param[in] owner 是否完全控制（是否管理对sock的释放操作）
     */
    SocketStream(Socket::ptr socket, bool owner = true);

    /**
     * @brief 析构函数
     * @details 如果m_owner=true,则close
     */
    virtual ~SocketStream();

    //返回Socket
    Socket::ptr getSocket() const { return m_socket; }

    //返回是否连接
    bool isConnected() const;

    //获取远端地址
    Address::ptr getRemoteAddress();
    //获取本地地址
    Address::ptr getLocalAddress();
    //以字符串方式返回远端地址
    std::string getRemoteAddressString();
    //以字符串方式返回本地地址
    std::string getLocalAddressString();

//=====================================================================
    //关闭流
    virtual void close() override;

    /**
     * @brief 读数据
     * @param[out] buffer 接收数据的内存
     * @param[in] length 接收数据的内存大小
     * @return
     *      @retval >0 返回接收到的数据的实际大小
     *      @retval =0 被关闭
     *      @retval <0 出现流错误
     */
    virtual int read(void *buffer, size_t count) override;

    /**
     * @brief 读数据
     * @param[out] ba 接收数据的ByteArray
     * @param[in] length 接收数据的内存大小
     * @return
     *      @retval >0 返回接收到的数据的实际大小
     *      @retval =0 被关闭
     *      @retval <0 出现流错误
     */
    virtual int read(ByteArray::ptr ba, size_t length) override;

    /**
     * @brief 写数据
     * @param[in] ba 写数据的ByteArray
     * @param[in] length 写入数据的内存大小
     * @return
     *      @retval >0 返回写入到的数据的实际大小
     *      @retval =0 被关闭
     *      @retval <0 出现流错误
     */
    virtual int write(const void *buffer, size_t count) override;

    /**
     * @brief 写数据
     * @param[in] ba 写数据的ByteArray
     * @param[in] length 写入数据的内存大小
     * @return
     *      @retval >0 返回写入到的数据的实际大小
     *      @retval =0 被关闭
     *      @retval <0 出现流错误
     */
    virtual int write(ByteArray::ptr ba, size_t length) override;

private:
    Socket::ptr m_socket;
    bool m_owner;   //是否主控（是否管理对sock的释放操作）
};

#endif	/* SOCKET_STREAM_H */
